package com.bank.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.beans.factory.annotation.Autowired;
import com.bank.service.UserInfoService;
import com.bank.service.CardInfoService;
import com.bank.service.DepositService;
import com.bank.service.TransactionService;
import com.bank.entity.UserInfo;
import com.bank.entity.CardInfo;
import com.bank.entity.Deposit;
import com.bank.entity.Transaction;
import com.bank.dto.CardInfoDTO;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import java.nio.charset.StandardCharsets;
import java.io.StringWriter;
import java.io.PrintWriter;

@Controller
@RequestMapping("/admin")
public class AdminController {
    
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private CardInfoService cardInfoService;
    @Autowired
    private DepositService depositService;
    @Autowired
    private TransactionService transactionService;
    
    @GetMapping("/login")
    public String login() {
        return "admin/login";
    }
    
    @PostMapping("/login")
    public String doLogin() {
        // TODO: 实现登录逻辑
        return "redirect:/admin/main";
    }
    
    @GetMapping("/main")
    public String main() {
        return "admin/main";
    }
    
    @GetMapping("/user")
    public String userManagement(@RequestParam(value = "keyword", required = false) String keyword, Model model) {
        java.util.List<com.bank.entity.UserInfo> users;
        if (keyword != null && !keyword.trim().isEmpty()) {
            users = userInfoService.findByKeyword(keyword.trim());
        } else {
            users = userInfoService.findAll();
        }
        model.addAttribute("users", users);
        model.addAttribute("keyword", keyword);
        return "admin/user";
    }
    
    @GetMapping("/user/export")
    public ResponseEntity<byte[]> exportUsersToCsv(@RequestParam(value = "keyword", required = false) String keyword) {
        // 1. 获取用户数据
        java.util.List<UserInfo> users;
        if (keyword != null && !keyword.trim().isEmpty()) {
            users = userInfoService.findByKeyword(keyword.trim());
        } else {
            users = userInfoService.findAll();
        }

        // 2. 生成CSV内容
        StringWriter stringWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(stringWriter);
        
        // 写入CSV表头
        writer.println("用户ID,姓名,身份证号,手机号,地址");

        // 写入数据行
        for (UserInfo user : users) {
            writer.println(
                String.join(",",
                    "\"" + user.getCustomerID() + "\"",
                    "\"" + user.getCustomerName() + "\"",
                    "\"=\"" + user.getPid() + "\"\"",
                    "\"=\"" + user.getTelephone() + "\"\"",
                    "\"" + user.getAddress() + "\""
                )
            );
        }

        // 3. 设置HTTP响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("text", "csv", StandardCharsets.UTF_8));
        headers.setContentDispositionFormData("attachment", "users.csv");

        // 添加BOM来帮助Excel正确识别UTF-8编码
        byte[] bom = {(byte)0xEF, (byte)0xBB, (byte)0xBF};
        byte[] csvBytes = stringWriter.toString().getBytes(StandardCharsets.UTF_8);
        byte[] content = new byte[bom.length + csvBytes.length];
        System.arraycopy(bom, 0, content, 0, bom.length);
        System.arraycopy(csvBytes, 0, content, bom.length, csvBytes.length);

        return new ResponseEntity<>(content, headers, org.springframework.http.HttpStatus.OK);
    }
    
    @GetMapping("/card")
    public String cardManagement(@RequestParam(value = "keyword", required = false) String keyword, Model model) {
        java.util.List<CardInfoDTO> cards;
        if (keyword != null && !keyword.trim().isEmpty()) {
            cards = cardInfoService.findByKeywordWithCustomerName(keyword.trim());
        } else {
            cards = cardInfoService.findAllWithCustomerName();
        }
        model.addAttribute("cards", cards);
        model.addAttribute("keyword", keyword);
        return "admin/card";
    }
    
    @GetMapping("/card/export")
    public ResponseEntity<byte[]> exportCardsToCsv(@RequestParam(value = "keyword", required = false) String keyword) {
        // 1. 获取数据
        java.util.List<CardInfoDTO> cards;
        if (keyword != null && !keyword.trim().isEmpty()) {
            cards = cardInfoService.findByKeywordWithCustomerName(keyword.trim());
        } else {
            cards = cardInfoService.findAllWithCustomerName();
        }

        // 2. 生成CSV内容
        StringWriter stringWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(stringWriter);
        
        writer.println("卡号,用户ID,姓名,存款类型,余额,开户日期,状态,币种ID,开户金额");

        for (CardInfoDTO card : cards) {
            writer.println(
                String.join(",",
                    "\"=\"" + card.getCardID() + "\"\"",
                    "\"" + card.getCustomerID() + "\"",
                    "\"" + card.getCustomerName() + "\"",
                    "\"" + card.getSavingName() + "\"",
                    "\"" + card.getBalance() + "\"",
                    "\"" + (card.getOpenDate() != null ? new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(card.getOpenDate()) : "") + "\"",
                    "\"" + card.getIsReportLoss() + "\"",
                    "\"" + card.getCurID() + "\"",
                    "\"" + card.getOpenMoney() + "\""
                )
            );
        }

        // 3. 设置HTTP响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("text", "csv", StandardCharsets.UTF_8));
        headers.setContentDispositionFormData("attachment", "cards.csv");

        byte[] bom = {(byte)0xEF, (byte)0xBB, (byte)0xBF};
        byte[] csvBytes = stringWriter.toString().getBytes(StandardCharsets.UTF_8);
        byte[] content = new byte[bom.length + csvBytes.length];
        System.arraycopy(bom, 0, content, 0, bom.length);
        System.arraycopy(csvBytes, 0, content, bom.length, csvBytes.length);

        return new ResponseEntity<>(content, headers, org.springframework.http.HttpStatus.OK);
    }
    
    @GetMapping("/deposit")
    public String depositManagement(@RequestParam(value = "keyword", required = false) String keyword, Model model) {
        java.util.List<com.bank.entity.Deposit> deposits;
        if (keyword != null && !keyword.trim().isEmpty()) {
            String trimmed = keyword.trim();
            if (trimmed.matches("\\d+")) {
                // 纯数字，精确查ID
                deposits = depositService.findBySavingID(Long.valueOf(trimmed));
            } else {
                // 文字，模糊查名称
                deposits = depositService.findBySavingNameContaining(trimmed);
            }
        } else {
            deposits = depositService.findAll();
        }
        model.addAttribute("deposits", deposits);
        model.addAttribute("keyword", keyword);
        return "admin/deposit";
    }
    
    @GetMapping("/deposit/export")
    public ResponseEntity<byte[]> exportDepositsToCsv(@RequestParam(value = "keyword", required = false) String keyword) {
        // 1. 获取数据
        java.util.List<com.bank.entity.Deposit> deposits;
        if (keyword != null && !keyword.trim().isEmpty()) {
            String trimmed = keyword.trim();
            if (trimmed.matches("\\d+")) {
                deposits = depositService.findBySavingID(Long.valueOf(trimmed));
            } else {
                deposits = depositService.findBySavingNameContaining(trimmed);
            }
        } else {
            deposits = depositService.findAll();
        }

        // 2. 生成CSV内容
        StringWriter stringWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(stringWriter);
        
        writer.println("类型ID,名称,描述");

        for (Deposit deposit : deposits) {
            writer.println(
                String.join(",",
                    "\"" + deposit.getSavingID() + "\"",
                    "\"" + deposit.getSavingName() + "\"",
                    "\"" + deposit.getDescrip() + "\""
                )
            );
        }

        // 3. 设置HTTP响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("text", "csv", StandardCharsets.UTF_8));
        headers.setContentDispositionFormData("attachment", "deposits.csv");

        byte[] bom = {(byte)0xEF, (byte)0xBB, (byte)0xBF};
        byte[] csvBytes = stringWriter.toString().getBytes(StandardCharsets.UTF_8);
        byte[] content = new byte[bom.length + csvBytes.length];
        System.arraycopy(bom, 0, content, 0, bom.length);
        System.arraycopy(csvBytes, 0, content, bom.length, csvBytes.length);

        return new ResponseEntity<>(content, headers, org.springframework.http.HttpStatus.OK);
    }
    
    @GetMapping("/trade")
    public String tradeManagement(@RequestParam(value = "keyword", required = false) String keyword, Model model) {
        java.util.List<com.bank.entity.Transaction> trades;
        if (keyword != null && !keyword.trim().isEmpty()) {
            trades = transactionService.findByKeyword(keyword.trim());
        } else {
            trades = transactionService.findAll();
        }
        model.addAttribute("trades", trades);
        model.addAttribute("keyword", keyword);
        return "admin/trade";
    }

    @GetMapping("/trade/export")
    public ResponseEntity<byte[]> exportTradesToCsv(@RequestParam(value = "keyword", required = false) String keyword) {
        // 1. 获取数据
        java.util.List<com.bank.entity.Transaction> trades;
        if (keyword != null && !keyword.trim().isEmpty()) {
            trades = transactionService.findByKeyword(keyword.trim());
        } else {
            trades = transactionService.findAll();
        }

        // 2. 生成CSV内容
        StringWriter stringWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(stringWriter);
        
        writer.println("交易时间,交易类型,卡号,交易金额,备注");

        for (Transaction trade : trades) {
            writer.println(
                String.join(",",
                    "\"" + (trade.getTradeDate() != null ? new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(trade.getTradeDate()) : "") + "\"",
                    "\"" + trade.getTradeType() + "\"",
                    "\"=\"" + trade.getCardID() + "\"\"",
                    "\"" + trade.getTradeMoney() + "\"",
                    "\"" + trade.getRemark() + "\""
                )
            );
        }

        // 3. 设置HTTP响应头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(new MediaType("text", "csv", StandardCharsets.UTF_8));
        headers.setContentDispositionFormData("attachment", "trades.csv");

        byte[] bom = {(byte)0xEF, (byte)0xBB, (byte)0xBF};
        byte[] csvBytes = stringWriter.toString().getBytes(StandardCharsets.UTF_8);
        byte[] content = new byte[bom.length + csvBytes.length];
        System.arraycopy(bom, 0, content, 0, bom.length);
        System.arraycopy(csvBytes, 0, content, bom.length, csvBytes.length);

        return new ResponseEntity<>(content, headers, org.springframework.http.HttpStatus.OK);
    }
    
    // 用户管理 - 编辑
    @GetMapping("/user/edit/{id}")
    public String editUser(@PathVariable Long id, Model model) {
        UserInfo user = userInfoService.findById(id).orElse(null);
        model.addAttribute("user", user);
        return "admin/user-edit";
    }
    
    @PostMapping("/user/edit")
    @Transactional
    public String doEditUser(@ModelAttribute UserInfo user) {
        userInfoService.save(user);
        // 同步更新所有银行卡的姓名
        cardInfoService.syncCustomerNameToCards(user.getCustomerID(), user.getCustomerName());
        return "redirect:/admin/user";
    }
    
    // 用户管理 - 删除
    @GetMapping("/user/delete/{id}")
    @Transactional
    public String deleteUser(@PathVariable Long id) {
        // 先删除该用户下所有银行卡
        cardInfoService.deleteByCustomerID(id);
        // 再删除用户
        userInfoService.deleteById(id);
        return "redirect:/admin/user";
    }
    
    // 显示添加用户页面
    @GetMapping("/user/add")
    public String addUserForm(Model model) {
        model.addAttribute("user", new UserInfo());
        return "admin/user-add";
    }

    // 处理添加用户表单提交
    @PostMapping("/user/add")
    @Transactional
    public String doAddUser(@ModelAttribute UserInfo user) {
        userInfoService.save(user);
        return "redirect:/admin/user";
    }
    
    // 银行卡管理 - 编辑
    @GetMapping("/card/edit/{id}")
    public String editCard(@PathVariable String id, Model model) {
        CardInfo card = cardInfoService.findById(id).orElse(null);
        String customerName = "";
        String telephone = "";
        String address = "";
        String pid = "";
        if (card != null && card.getCustomerID() != null) {
            UserInfo user = userInfoService.findById(card.getCustomerID()).orElse(null);
            if (user != null) {
                customerName = user.getCustomerName();
                telephone = user.getTelephone();
                address = user.getAddress();
                pid = user.getPid();
            }
        }
        model.addAttribute("card", card);
        model.addAttribute("depositTypes", depositService.findAll());
        model.addAttribute("customerName", customerName);
        model.addAttribute("telephone", telephone);
        model.addAttribute("address", address);
        model.addAttribute("pid", pid);
        return "admin/card-edit";
    }
    
    @PostMapping("/card/edit")
    @Transactional
    public String doEditCard(@ModelAttribute CardInfo card,
                             @RequestParam String telephone,
                             @RequestParam String address,
                             @RequestParam String pid) {
        // 只查找和更新，不新建用户
        if (card.getCustomerID() != null) {
            UserInfo user = userInfoService.findById(card.getCustomerID()).orElse(null);
            if (user != null) {
                user.setCustomerName(card.getCustomerName());
                user.setTelephone(telephone);
                user.setAddress(address);
                user.setPid(pid);
                userInfoService.save(user);
            }
        }
        cardInfoService.save(card); // 只保存银行卡
        return "redirect:/admin/card";
    }
    
    // 银行卡管理 - 删除
    @GetMapping("/card/delete/{id}")
    @Transactional
    public String deleteCard(@PathVariable String id) {
        cardInfoService.deleteById(id);
        return "redirect:/admin/card";
    }
    
    // 显示添加银行卡页面
    @GetMapping("/card/add")
    public String addCardForm(Model model) {
        CardInfo card = new CardInfo();
        model.addAttribute("card", card);
        model.addAttribute("depositTypes", depositService.findAll());
        // 查询所有用户用于下拉选择
        java.util.List<UserInfo> users = userInfoService.findAll();
        model.addAttribute("users", users);
        return "admin/card-add";
    }

    // 处理添加银行卡表单提交
    @PostMapping("/card/add")
    @Transactional
    public String doAddCard(@ModelAttribute CardInfo card,
                            @RequestParam String telephone,
                            @RequestParam String address,
                            @RequestParam String pid) {
        // 判断用户ID是否存在
        UserInfo user = null;
        if (card.getCustomerID() != null) {
            user = userInfoService.findById(card.getCustomerID()).orElse(null);
        }
        if (user == null) {
            // 用户不存在，新建
            user = new UserInfo();
            user.setCustomerName(card.getCustomerName());
            user.setTelephone(telephone);
            user.setAddress(address);
            user.setPid(pid);
            userInfoService.save(user);
            card.setCustomerID(user.getCustomerID()); // 用新ID
        } else {
            // 用户已存在，更新信息
            user.setCustomerName(card.getCustomerName());
            user.setTelephone(telephone);
            user.setAddress(address);
            user.setPid(pid);
            userInfoService.save(user);
            card.setCustomerID(user.getCustomerID()); // 保持原ID
        }
        cardInfoService.save(card);
        return "redirect:/admin/card";
    }
    
    // 显示添加存款类型页面
    @GetMapping("/deposit/add")
    public String addDepositForm(Model model) {
        model.addAttribute("deposit", new Deposit());
        return "admin/deposit-add";
    }

    // 处理添加存款类型表单
    @PostMapping("/deposit/add")
    @Transactional
    public String doAddDeposit(@ModelAttribute Deposit deposit) {
        depositService.save(deposit);
        return "redirect:/admin/deposit";
    }

    // 显示编辑存款类型页面
    @GetMapping("/deposit/edit/{id}")
    public String editDeposit(@PathVariable Long id, Model model) {
        Deposit deposit = depositService.findById(id).orElse(null);
        model.addAttribute("deposit", deposit);
        return "admin/deposit-edit";
    }

    // 处理编辑存款类型表单
    @PostMapping("/deposit/edit")
    @Transactional
    public String doEditDeposit(@ModelAttribute Deposit deposit) {
        depositService.save(deposit);
        return "redirect:/admin/deposit";
    }
    
    // 存款管理 - 删除
    @GetMapping("/deposit/delete/{id}")
    @Transactional
    public String deleteDeposit(@PathVariable Long id) {
        depositService.deleteById(id);
        return "redirect:/admin/deposit";
    }
    
    // 交易管理 - 删除
    @GetMapping("/trade/delete")
    @Transactional
    public String deleteTrade(@RequestParam String cardID, @RequestParam String tradeDate) {
        try {
            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            java.util.Date date = sdf.parse(tradeDate);
            transactionService.deleteByCardIDAndTradeDate(cardID, date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:/admin/trade";
    }
    
    @GetMapping("/logout")
    public String logout() {
        return "redirect:/";
    }
} 